<!--
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2025-06-05 21:41:31
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-06-18 15:31:54
 * @FilePath: \vue3_admin_template\project\src\views\product\spu\spuForm.vue
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
  <div>
    <el-form ref="form" label-width="100px">
      <el-form-item label="SPU名称">
        <el-input
          placeholder="请你输入spu名称"
          v-model="SpuParams.spuName"
        ></el-input>
      </el-form-item>
      <el-form-item label="SPU品牌">
        <el-select v-model="SpuParams.tmId">
          <el-option
            v-for="item in AllTredeMArk"
            :key="item.id"
            :label="item.tmName"
            :value="item.id"
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="SPU描述">
        <el-input
          placeholder="请你输入spu描述"
          v-model="SpuParams.description"
        ></el-input>
      </el-form-item>
      <!--  v-model:file-list 是默认展示图片的 
        action:'上传图片的服务器地址'
        list-type:照片显示的形式
      -->
      <el-form-item label="SPU图标">
        <el-upload
          v-model:file-list="imgList"
          action="/api/admin/product/fileUpload"
          list-type="picture-card"
          :before-upload="beforeAvatarUpload"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleRemove"
        >
          <el-icon><Plus /></el-icon>
        </el-upload>

        <el-dialog v-model="dialogVisible">
          <img
            w-full
            :src="dialogImageUrl"
            alt="Preview Image"
            style="width: 100%; height: 100%"
          />
        </el-dialog>
      </el-form-item>
      <el-form-item label="SPU销售属性">
        <!-- 展示销售属性下拉菜单 -->
        <el-select
          :placeholder="
            unSelectSaleAttr.length
              ? `还未选择${unSelectSaleAttr.length}个`
              : '无'
          "
          v-model="saleAttrIdAndValueName"
          clearable
        >
          <el-option
            :value="`${item.id}:${item.name}`"
            v-for="item in unSelectSaleAttr"
            :key="item.id"
            :label="item.name"
          ></el-option>
        </el-select>
        <el-button
          @click="addSaleAttr"
          type="primary"
          icon="Plus"
          :disabled="saleAttrIdAndValueName == '' ? true : false"
        >
          添加属性
        </el-button>
        <el-table border :data="saleAttr" style="width: 100%; margin: 10px 0">
          <el-table-column
            type="index"
            label="序号"
            width="100px"
          ></el-table-column>
          <el-table-column
            prop="saleAttrName"
            label="名字"
            width="200px"
          ></el-table-column>
          <el-table-column label="属性值">
            <!-- row 即当前属性 颜色 版本 尺寸属性-->
            <template #="{ row, $index }">
              <el-tag
                v-for="item in row.spuSaleAttrValueList"
                :key="item.id"
                closable
                style="margin: 2px 5px"
                @close="row.spuSaleAttrValueList.splice($index, 1)"
              >
                {{ item.saleAttrValueName }}
              </el-tag>
              <el-input
                v-if="row.isEdit"
                ref="inputFocus"
                v-model="row.saleAttrValue"
                @blur="toLook(row)"
                placeholder="请你输入属性值"
                size="small"
                style="width: 100px"
              ></el-input>
              <el-button
                v-else
                type="primary"
                size="small"
                icon="Plus"
                autofocus
                @click="addEdit(row)"
              ></el-button>
            </template>
          </el-table-column>
          <el-table-column prop="prop" label="操作" width="100px">
            <!-- 删除当前属性 -->
            <template #="{ row }">
              <el-button
                type="danger"
                size="small"
                icon="Delete"
                @click="saleAttr.splice(row.$index, 1)"
              ></el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>
      <el-form-item label="">
        <el-button
          type="primary"
          size="small"
          @click="saveAttr"
          :disabled="saleAttr.length > 0 ? false : true"
        >
          保存
        </el-button>
        <el-button type="primary" size="small" @click="cancel">取消</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup lang="ts">
import type {
  SpuData,
  AllTradeMark,
  TradeMark,
  SpuHasImg,
  SpuImg,
  SaleAttrResponseData,
  HasScaleAttrResponseData,
  SaleAttr,
  SaleAttrValue,
  HasScaleAttr,
} from '@/api/product/spu/type'
import {
  reqAllTradeMark,
  reqSpuImageList,
  reqSpuHasSaleAttr,
  reqAllSaleAttr,
  reqAddOrUpdateSpu,
} from '@/api/product/spu'
import { ref, computed, nextTick } from 'vue'
import { UploadProps, ElMessage } from 'element-plus'
const emit = defineEmits(['changeScene'])
//存储已有SPU全部数据
//品牌
let AllTredeMArk = ref<TradeMark[]>([])
//商品图片
let imgList = ref<SpuImg[]>([])
//已有的spu销售属性
let saleAttr = ref<SaleAttr[]>([])
//已有spu的所有销售属性
let allSaleAttr = ref<HasScaleAttr[]>([])
//存储已有发SPU对象
let SpuParams = ref<SpuData>({
  category3Id: '',
  spuName: '',
  description: '',
  tmId: '',
  spuImageList: [],
  spuSaleAttrList: [],
})
//控制照片请预览放大图层显示和隐藏
let dialogVisible = ref<boolean>(false)
let dialogImageUrl = ref('') //照片墙图片预览地址
let inputFocus = ref() //获取el-input实例 实现自动聚焦
//计算出当前的SPU还未拥有放入销售属性
let unSelectSaleAttr = computed(() => {
  //全部销售属性:颜色,版本,尺码
  //已有的销售属性 颜色,版本
  let unSelectArr = allSaleAttr.value.filter((item) => {
    return saleAttr.value.every((item1) => {
      return item1.saleAttrName !== item.name
    })
  })
  return unSelectArr
})
//将来收集还未选择的销售属性的ID和属性值的名字
let saleAttrIdAndValueName = ref<string>('')
//点击取消按钮通知父组件切换场景为0,展示SPU的数据
const initHasSpuData = async (spu: SpuData) => {
  SpuParams.value = spu
  //spu即为父组件传递过来的有的SPU对象[不完整]
  //获取全部品牌数据
  let result: AllTradeMark = await reqAllTradeMark()
  //获取某一个品牌旗下的全部的售卖商品的图片'
  let result1: SpuHasImg = await reqSpuImageList(spu.id as number)
  //获取已有的spu销售属性数据
  let result2: SaleAttrResponseData = await reqSpuHasSaleAttr(spu.id as number)
  //   console.log(result2)
  //获取整个项目全部的spu销售属性
  let result3: HasScaleAttrResponseData = await reqAllSaleAttr()
  // console.log(result3)
  //存储全部的品牌数据
  AllTredeMArk.value = result.data
  //spu对应发图片
  imgList.value = result1.data.map((item) => {
    return {
      name: item.imgName,
      url: item.imgUrl,
    }
  })
  // 存储已有的spu销售属性
  saleAttr.value = result2.data
  //存储全部的销售属性
  allSaleAttr.value = result3.data
  // allSaleAttr.value = [
  // {
  //   "id": 1,
  //   "createTime": "2021-12-10 01:31:41",
  //   "updateTime": "2021-12-10 01:31:41",
  //   "name": "颜色"
  // },
  // {
  //   "id": 2,
  //   "createTime": "2021-12-10 01:31:41",
  //   "updateTime": "2021-12-10 01:31:41",
  //   "name": "版本"
  // },
  // {
  //   "id": 3,
  //   "createTime": "2021-12-10 01:31:41",
  //   "updateTime": "2021-12-10 01:31:41",
  //   "name": "尺码"
  // }
  //   ]
}
//添加新的SPU初始化方法
const initAddSpuData = async (c3Id: string) => {
  //清空每次新添加之前先清空数据
  Object.assign(SpuParams.value, {
    category3Id: '',
    spuName: '',
    description: '',
    tmId: '',
    spuImageList: [],
    spuSaleAttrList: [],
  })
  //清空照片墙
  imgList.value = []
  //清空销售属性
  saleAttr.value = []
  //清空选择的销售属性
  saleAttrIdAndValueName.value = ''
  SpuParams.value.category3Id = c3Id
  //获取全部品牌数据
  let result: AllTradeMark = await reqAllTradeMark()
  //存储全部的品牌数据
  AllTredeMArk.value = result.data
  let result3: HasScaleAttrResponseData = await reqAllSaleAttr()
  //存储全部的销售属性
  allSaleAttr.value = result3.data
}
//照片墙点击预览的时候按钮触发的钩子
const handlePictureCardPreview = (file: any) => {
  //预览照片弹出来
  dialogVisible.value = true
  dialogImageUrl.value = file.url
}
//照片墙预览删除按钮事件回调
const handleRemove = (file: any) => {
  console.log(file)
}

//上传图片组件-->上传图片之前触发的的钩子函数 用来限制图片大小等提示信息
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile: any) => {
  //上传图片成功之前触发,上传文件之前可以用来约束文件的类型和大小
  //上传文件的类型:png|jpg|gif 4M
  if (
    rawFile.type == 'image/jpeg' ||
    rawFile.type == 'image/png' ||
    rawFile.type == 'image/gif'
  ) {
    if (rawFile.size / 1024 / 1024 < 4) {
      return true
    } else {
      ElMessage({
        type: 'error',
        message: '上传文件大小应小于4M',
      })
      return false
    }
  } else {
    ElMessage({
      type: 'error',
      message: '上传文件格式务必是PNG|JPG|GIF',
    })
    return false
  }
}
//添加销售属性的方法
const addSaleAttr = () => {
  const [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':')
  //准备一个新的销售属性对象:将来带给服务器
  let newSaleAttr: SaleAttr = {
    baseSaleAttrId,
    saleAttrName,
    spuSaleAttrValueList: [],
  }
  //追加到销售属性数组中
  saleAttr.value.push(newSaleAttr)
  saleAttrIdAndValueName.value = ''
}
//添加属性值事件回调
const addEdit = (row: SaleAttr) => {
  //给当前销售属性添加一个标识isEdit 等于 true即为编辑模式显示input框, 等于false即为 查看模式 隐藏input框
  row.isEdit = true
  //给当前属性添加saleAttrValue 属性用来保存 新添加的属性值
  row.saleAttrValue = ''
  nextTick(() => {
    //新添加属性值的时候 el-input框自动获取焦点
    inputFocus.value.focus()
  })
}
//input输入框失去焦点事件回调
const toLook = (row: SaleAttr) => {
  //整理收集属性的ID与属性值名字
  const { baseSaleAttrId, saleAttrValue } = row
  //整理成服务器需要的属性值形式
  const newSaleAttrValue: SaleAttrValue = {
    baseSaleAttrId,
    saleAttrValueName: saleAttrValue as string,
    // createTime:null,
    // id:row.id,
    // saleAttrName:row.saleAttrName,
    // spuId:row.spuId,
  }
  //非法情况判断
  if ((saleAttrValue as string).trim() == '') {
    ElMessage({
      type: 'error',
      message: '属性值不能为空',
    })
    return
  }
  //重复值
  let repeat = row.spuSaleAttrValueList.find((item) => {
    return item.saleAttrValueName == saleAttrValue
  })
  if (repeat) {
    ElMessage({
      type: 'error',
      message: '属性值重复!',
    })
    return
  }

  //追加新的属性值对象
  row.spuSaleAttrValueList.push(newSaleAttrValue)
  //切换为查看模式
  row.isEdit = false
}
//添加属性保存事件回调
const saveAttr = async () => {
  //整理参数
  //照片墙的参数整理
  SpuParams.value.spuImageList = imgList.value.map((item: any) => {
    return {
      imgName: item.name,
      imgUrl: (item.response && item.response.data) || item.url,
    }
  })
  //销售属性的数据整理
  SpuParams.value.spuSaleAttrList = saleAttr.value
  //发送请求;添加spu|更新已有的spu
  let result: any = await reqAddOrUpdateSpu(SpuParams.value)
  if (result.code == 200) {
    ElMessage({
      type: 'success',
      message: SpuParams.value.id ? '更新SPU成功' : '添加SPU成功',
    })
    ///通知父组件将场景切换为0
    emit('changeScene', {
      flag: 0,
      params: SpuParams.value.id ? 'update' : 'add',
    })
  } else {
    ElMessage({
      type: 'error',
      message: SpuParams.value.id ? '更新SPU失败' : '添加SPU失败',
    })
  }

  //成功
  //失败
}
defineExpose({
  initHasSpuData,
  initAddSpuData,
})
const cancel = () => {
  emit('changeScene', { flag: 0, params: 'update' })
}
</script>

<style lang="scss" scoped></style>
